<template>
  <view class="ve-tabs" id="order-tabs-labels">
    <scroll-view
      v-if="!refresh"
      scroll-x
      :scroll-left="scrollLeft"
      :scroll-with-animation="scrollWithAnimation"
      class="scroll-view"
      show-scrollbar="false"
    >
      <view class="ve-tabs-list" :class="{ 'scorll-flex': list.length <= 4 }">
        <view
          v-for="(item, index) in list"
          :id="'order-tabs-labels' + index"
          :key="index"
          @tap="selectTab(item, index)"
          class="ve-tabs-item"
          :class="{ 'is-actived': modelValue == item.value }"
        >
          {{ item.name }}
          <text>({{ item.num > 999 ? '999+' : item.num || 0 }})</text>
        </view>
      </view>
    </scroll-view>
  </view>
</template>

<script setup>
  import { ref, computed, watch, nextTick, onMounted } from 'vue'
  const props = defineProps({
    list: {
      type: Array,
      // 1=未处理未收款，2=未处理已收款，3=已处理未收款，4=超过7天未处理，5=超过15天未处理，6=承租人不配合处理
      default: () => [],
    },
    modelValue: {
      type: Number,
    },
  })
  const emits = defineEmits(['update:modelValue', 'change'])

  const activedIndex = ref(0) // 激活的下标
  // order-tabs-labels dom 相关数据
  const wrapperRectWidth = ref(0) // 屏幕宽度，单位为px
  const wrapperRectLeft = ref(0) // 父元素(tabs组件)到屏幕左边的距离
  const scrollWithAnimation = ref(true)

  const scrollLeft = ref(0) // 滚动scroll-view的左边滚动距离
  const refresh = ref(false) // 强制刷新 否则计算坐标出现异常
  const tabsRectInfo = ref([]) // 所有的tab rect 数据
  onMounted(() => {
    const query = uni.createSelectorQuery().in(this)
    query
      .select('#order-tabs-labels')
      .boundingClientRect((tabRect) => {
        // tabs组件距离屏幕左边的宽度
        wrapperRectLeft.value = tabRect.left
        // tabs组件的宽度
        wrapperRectWidth.value = tabRect.width
      })
      .exec()
  })

  // 获取 tabs rect 数据
  const getTabsRect = (callback) => {
    // 创建节点查询
    const query = uni.createSelectorQuery().in(this)
    // 历遍所有tab，这里是执行了查询，最终使用exec()会一次性返回查询的数组结果
    for (let i = 0; i < props.list.length; i++) {
      // 只要size和rect两个参数
      query.select(`#order-tabs-labels${i}`).fields({
        size: true,
        rect: true,
      })
    }
    // 执行查询，一次性获取多个结果
    query.exec(
      function (res) {
        callback(res)
      }.bind(this),
    )
  }

  // 选择tab
  const selectTab = (item, index) => {
    // 点击当前活动tab
    scrollByIndex(index)
    // 赋值
    const value = props.modelValue == item.value ? undefined : item.value
    emits('update:modelValue', value)
    emits('change', value, item)
  }
  // 控制滚动到位置
  const scrollByIndex = (index) => {
    activedIndex.value = index || 0
    // 当前活动tab的布局信息，有tab菜单的width和left(为元素左边界到父元素左边界的距离)等信息
    let tabInfo = tabsRectInfo.value[activedIndex.value]
    if (!tabInfo) return
    // 活动tab的宽度
    let tabWidth = tabInfo.width
    // 活动item的左边到tabs组件左边的距离，用item的left减去tabs的left
    let offsetLeft = tabInfo.left - wrapperRectLeft.value
    // 将活动的tabs-item移动到屏幕正中间，实际上是对scroll-view的移动
    let left = offsetLeft - (wrapperRectWidth.value - tabWidth) / 2
    scrollLeft.value = left < 0 ? 0 : left
  }

  watch(
    () => props.list,
    async () => {
      await nextTick()
      getTabsRect((res) => {
        tabsRectInfo.value = res
      })
    },
    { immediate: true, deep: true },
  )

  // 更新 tabs 位置信息
  // 获取 labels 数量之后，原先存储的位置信息已经不对了，此处进行修正
  const updateTabsRect = async () => {
    await nextTick()
    getTabsRect((res) => {
      const labels = checkedLabels.value
      if (labels?.length > 0) {
        activedIndex.value = labels[0]
      }
      tabsRectInfo.value.forEach((item, index) => {
        if (res[index]) {
          item.left = res[index].left + scrollLeft.value
        }
      })
      scrollWithAnimation.value = false
      scrollByIndex()
      setTimeout(() => {
        scrollWithAnimation.value = true
      }, 100)
    })
  }

  defineExpose({
    scrollByIndex,
  })
</script>
<style lang="scss" scoped>
  .scroll-view {
    white-space: nowrap;
    width: 100%;
    height: 100%;
  }

  .ve-tabs {
    position: relative;
    white-space: nowrap;

    &-list {
      position: relative;
      width: 100%;
      height: 100%;
      display: flex;
    }

    &-item {
      // flex: 1;
      color: #55585f;
      font-size: 24rpx;
      height: 48rpx;
      line-height: 44rpx;
      padding: 0 16rpx;
      border-radius: 4rpx;
      border: 2rpx solid #dadbdd;
      margin-right: 16rpx;

      &.is-actived {
        background: #e0edff;
        border: 2rpx solid #3072f6;
        color: #3072f6;
      }
    }
  }
</style>
